#include <d3d9.h>
#include <d3dx9.h>
#include "Direct3d.h"
#include "Sprite.h"



IDirect3DDevice9* cSprite::device = NULL;
extern int xRes,yRes;

cSprite::cSprite() : Vertices(*this)
{
	vb = NULL;
	tex = NULL;
	sizeY = sizeX = 0;
}

void cSprite::SetDevice(IDirect3DDevice9* dev)
{
	device = dev;
}

bool cSprite::LoadFromFile(const char* fileName)
{
	if(device == NULL)
		return false;

	HRESULT hr;
	D3DSURFACE_DESC TextureInfo;
	
	hr = D3DXCreateTextureFromFileEx(device,fileName,D3DX_DEFAULT,D3DX_DEFAULT,D3DX_DEFAULT,0,D3DFMT_A8R8G8B8,D3DPOOL_MANAGED,D3DX_FILTER_TRIANGLE,D3DX_FILTER_TRIANGLE,0xFF000000,NULL,NULL,&tex);

	if(FAILED(hr))
		return false;

	hr = device->CreateVertexBuffer(sizeof(sVertex) * 4, 0,
						   D3DFVF_TLVERTEX, D3DPOOL_MANAGED, &vb, NULL);
	if(FAILED(hr))
		return false;

	hr = tex->GetLevelDesc(0,&TextureInfo);
	if(FAILED(hr))
		return false;
	sizeX = TextureInfo.Width;
	sizeY = TextureInfo.Height;
	return true;
}

void cSprite::Render()const
{
	sVertex* tmp;
	sVertex* vert = Vertices.GetVertices();
	vb->Lock(0, 0, (void**)&tmp, 0);
	memcpy(tmp,vert,sizeof(sVertex)*4);
	delete []vert;
	vb->Unlock();
	
	device->SetStreamSource(0, vb, 0, sizeof(sVertex));
	device->SetTexture (0, tex);
	device->SetFVF(D3DFVF_TLVERTEX);

	device->SetRenderState(D3DRS_LIGHTING,false);
	
	device->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
	device->SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_DIFFUSE);
	device->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_MODULATE);
	
	device->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
	device->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
	device->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);

    device->DrawPrimitive (D3DPT_TRIANGLESTRIP, 0, 2);
}

int cSprite::GetX()const
{
	return sizeX;
}
int cSprite::GetY()const
{
	return sizeY;
}

void cSprite::Release()
{
	if(vb)
		vb->Release();
	if(tex)
		tex->Release();
	sizeX = sizeY = 0;
}

cSprite::~cSprite()
{
	Release();
}

cVertices::cVertices(const cSprite& s) :  sprite(s)
{

}

void cVertices::SetPosition (D3DXVECTOR2 VecPos)const
{
	pos=VecPos;
}
void cVertices::SetRect(float p1,float p2,float p3 ,float p4)const
{
	u1=p1;
	v1=p2;
	u2=p3;
	v2=p4;
}
void cVertices::SetScale(float Scale)const
{
	scale=Scale;
}
void cVertices::SetAngle(float Angle)const
{
	angle=Angle;
}
void cVertices::SetColor(D3DCOLOR Color)const
{
	color=Color;
}
void cVertices :: SetLeft(bool Left)const
{
	left = Left;
}

sVertex* cVertices::GetVertices()const
{
	int i;
	float x,y;
	sVertex* vertices;
	if(left)
		vertices = GetVerticesLeft();
	else
		vertices = GetVerticesRight();

	float Cos = cos(angle);
	float Sin = sin(angle);

	for(i=0; i<4; i++)
	{
		x = vertices[i].x;
		y = vertices[i].y;
		vertices[i].x = x*Cos + y*Sin + pos.x;
		vertices[i].y = -x*Sin + y*Cos + pos.y;
	}
	
	return vertices;
}

sVertex* cVertices::GetVerticesRight()const
{
	sVertex* vertices = new sVertex[4];
	float finalSizeX = (float)sprite.GetX()/2.0f*scale;
	float finalSizeY = (float)sprite.GetY()/2.0f*scale;
	
	vertices[0].color = color;
	vertices[0].x = -finalSizeX;
	vertices[0].y = -finalSizeY;
	vertices[0].z = 0.0f;
	vertices[0].rhw = 1.0f;
	vertices[0].u = u1;
	vertices[0].v = v1;

	vertices[1].color = color;
	vertices[1].x = finalSizeX;
	vertices[1].y = -finalSizeY;
	vertices[1].z = 0.0f;
	vertices[1].rhw = 1.0f;
	vertices[1].u = u2;
	vertices[1].v = v1;

	vertices[2].color = color;
	vertices[2].x = -finalSizeX;
	vertices[2].y = finalSizeY;
	vertices[2].z = 0.0f;
	vertices[2].rhw = 1.0f;
	vertices[2].u = u1;
	vertices[2].v = v2;

	vertices[3].color = color;
	vertices[3].x = finalSizeX;
	vertices[3].y = finalSizeY;
	vertices[3].z = 0.0f;
	vertices[3].rhw = 1.0f;
	vertices[3].u = u2;
	vertices[3].v = v2;	

	return vertices;
}

sVertex* cVertices::GetVerticesLeft()const
{
	sVertex* vertices = new sVertex[4];;
	float finalSizeX = (float)sprite.GetX()/2.0f*scale;
	float finalSizeY = (float)sprite.GetY()/2.0f*scale;
	
	vertices[0].color = color;
	vertices[0].x = -finalSizeX;
	vertices[0].y = -finalSizeY;
	vertices[0].z = 0.0f;
	vertices[0].rhw = 1.0f;
	vertices[0].u = u2;
	vertices[0].v = v1;

	vertices[1].color = color;
	vertices[1].x = finalSizeX;
	vertices[1].y = -finalSizeY;
	vertices[1].z = 0.0f;
	vertices[1].rhw = 1.0f;
	vertices[1].u = u1;
	vertices[1].v = v1;

	vertices[2].color = color;
	vertices[2].x = -finalSizeX;
	vertices[2].y = finalSizeY;
	vertices[2].z = 0.0f;
	vertices[2].rhw = 1.0f;
	vertices[2].u = u2;
	vertices[2].v = v2;

	vertices[3].color = color;
	vertices[3].x = finalSizeX;
	vertices[3].y = finalSizeY;
	vertices[3].z = 0.0f;
	vertices[3].rhw = 1.0f;
	vertices[3].u = u1;
	vertices[3].v = v2;

	return vertices;
}


void cSprite::DrawAt(int x,int y)
{
	Vertices.SetPosition(D3DXVECTOR2((float)x,(float)y));
	Vertices.SetLeft(false);
	Vertices.SetRect(0.0f,0.0f,1.0f,1.0f);
	Vertices.SetScale(1.0f);
	Vertices.SetColor(0xFFFFFFFF);
	Vertices.SetAngle(0);
	
	Render();
}

void cSprite::Draw()
{
	Vertices.SetPosition(D3DXVECTOR2((float)xRes/2,(float)yRes/2));
	Vertices.SetLeft(false);
	Vertices.SetRect(0.0f,0.0f,1.0f,1.0f);
	Vertices.SetScale(1.0f);
	Vertices.SetColor(0xFFFFFFFF);
	Vertices.SetAngle(0);
	Render();
}